﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System.Collections.Generic;
using ScrumTable.Common;
using ScrumTable.Common.Collections;
using ScrumTable.DL.Data.Common;
using ScrumTable.DL.Data.Schema;

#endregion

namespace ScrumTable.DL.Data.Generic
{


    /// <summary>
    /// The data storage interface contains the data access objects
    /// required by the ScrumTable.
    /// 
    /// The TFS driver provides the following data access objects:
    ///  - Members
    ///  - Projects
    ///  - Iterations
    ///  - UserStories
    ///  - Tasks
    /// </summary>
    public class DataStorage : DisposeBase, IDataStorage
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        private readonly Dictionary<string, DataAccessObjectBase> _dataAccessObjects =
            new Dictionary<string, DataAccessObjectBase>();
        
        private readonly GenericDataContextBase _context;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the data access object with the given name.
        /// </summary>
        /// <param name="name">Name of the data access object to obtain.</param>
        /// <returns>Returns the retrieved data acces object.</returns>
        public IDataAccessObject this[string name]
        {
            get { return _dataAccessObjects[name]; }
        }

        /// <summary>
        /// Gets the top context object.
        /// </summary>
        internal GenericDataContextBase Context { get { return _context; } }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new DataContext instance. This constructor is used in
        /// the current library only.
        /// </summary>
        internal DataStorage(GenericDataContextBase context)
        {
            PreCondition.AssertNotNull(context, "context");

            _context = context;

            _dataAccessObjects[_context.Schema.IterationSchema] = new IterationDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.MemberSchema] = new MemberDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.ProjectSchema] = new ProjectDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.TaskSchema] = new TaskDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.UserStorySchema] = new UserStoryDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.BugSchema] = new BugDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.TypeSchema] = new TypeDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.ReportSchema] = new ReportDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.TransitionSchema] = new TransitionDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.AttachmentSchema] = new AttachmentDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.MetaSchema] = new MetaDataAccessObject(_context);
            _dataAccessObjects[_context.Schema.TeamSchema] = new TeamDataAccessObject(_context);
        }

        /// <summary>
        /// This constructor is needed by the serialization routine.
        /// </summary>
        public DataStorage()
        {   
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Clears all data access objects in the current storage.
        /// </summary>
        public void Clear()
        {
            foreach (SchemaBase schema in Context.Schema.Schemata)
            {
                this[schema.SchemaName].Clear();
            }
        }

        /// <summary>
        /// Releases managed (c# or .net) resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            _dataAccessObjects.ForEach(daoPair => daoPair.Value.Dispose());
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #region Lifecycle Procedures

        /// <summary>
        /// Retrieves a call after the connection to the back-end system has
        /// been established.
        /// </summary>
        internal void OnConnected()
        {
            _dataAccessObjects.ForEach(daoPair => daoPair.Value.OnConnected());
        }

        /// <summary>
        /// Retrieves a call after the connection to the back-end system has
        /// been closed.
        /// </summary>
        internal void OnDisconnected()
        {
            _dataAccessObjects.ForEach(daoPair => daoPair.Value.OnDisconnected());
        }

        /// <summary>
        /// Retrieves a call after the initial data of the back-end system has
        /// been loaded.
        /// </summary>
        internal void OnInitialized()
        {
            _dataAccessObjects.ForEach(daoPair => daoPair.Value.OnInitialized());
        }

        #endregion

        #endregion
    }
}